home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / gen / dna09 / dna_v090.cpp next >
C/C++ Source or Header  |  1993-12-30  |  12KB  |  289 lines

  1. /*****************************************************************************         
  2.  Program : DNA.EXE v0.90
  3.  Purpose : Creates twisted ladder-shaped objects ( like DNA strands ) for the 
  4.            POV-Ray v2.x raytracer.   
  5.  Created : 12/30/93
  6.  By      : Rob Bryerton CIS [73747,433]           
  7.  File    : DNA_v090.CPP
  8.  Compiler: Microsoft C++ v8.00  
  9.  Model   : Medium
  10.  Comments: To do... add graphic preview, PolyRay and CTDS output
  11. *****************************************************************************/     
  12.  
  13. #include <fstream.h>
  14. #include <math.h>  
  15. #include <stdlib.h> 
  16. #include <string.h>
  17.  
  18. const char cVERSION[6] = "v0.90";  
  19.  
  20. void ErrExit(char *cMessage);
  21.  
  22. void GetAndValidateUserInput(char *cFileName, char *cUnionName, double *dHeight, 
  23.                              double *dRadius, double *dPartRadius, 
  24.                              long *lStepsPerRevolution, long *lTotalSteps,
  25.                              long *lConnectXsteps);
  26.  
  27. void ShowTitle();
  28.  
  29. inline void WriteCone(double dLastX, double dLastY, double dLastZ, 
  30.                double dX,     double dY,     double dZ,
  31.                double dRad,   ofstream& outfile, long *lGlobalCounter);  
  32.  
  33. void WriteFileEnd(ofstream& outfile, long lGlobalCounter); 
  34.  
  35. void WriteFileHeader(char *cFileName, char *cUnionName, ofstream& outfile, 
  36.                      double dHeight);
  37.  
  38. void WriteSceneFile(char *cFileName, char *cUnionName,
  39.                      double dHeight, double dRadius);                     
  40.  
  41. inline void WriteSphere(double dX, double dY, double dZ, double dRad, 
  42.                  ofstream& outfile, long *lGlobalCounter);
  43.  
  44. int main()
  45. {          
  46.     char   cFileName[80] = "DNA.INC";
  47.     char   cUnionName[80] = "DNA";    
  48.     double dRadius;    // the radius of the twister (DNA strand)
  49.     double dHeight;    // the overall length of the object
  50.     double dAngle;     // used to calc the polar coordinates
  51.     double dPartRadius;// the radius of the spheres (and cones) written at each coordinate
  52.     double dLastXpos1, dLastZpos1, dLastYpos; // stores the previous values... used
  53.     double dLastXpos2, dLastZpos2;            //    to connect the cones together    
  54.     long   lTotalSteps;// the TOTAL number of coords calc'd
  55.     long   lStepsPerRevolution;   
  56.     long   lGlobalCounter = 0;  // the overall # of objects written to file
  57.     long   lConnectorCounter = 0;  // ready for another connector??
  58.     long   lConnectXsteps;        // connect strands every X steps
  59.     
  60.     const double dPI = 3.1415926535897932384626;// hmmm 
  61.     ofstream     outfile;                       // the disk output file    
  62.     
  63.     ShowTitle();
  64.     
  65.     /* get some user input and check for validity */    
  66.     GetAndValidateUserInput(cFileName, cUnionName, &dHeight, 
  67.                             &dRadius, &dPartRadius, 
  68.                             &lStepsPerRevolution, &lTotalSteps, 
  69.                             &lConnectXsteps);
  70.     
  71.     /* Open file for output */
  72.     cout<< "\nCreating data file " << cFileName << endl;
  73.     outfile.open(cFileName,ios::out);            //    try to open a disk file
  74.     if(! outfile)     ErrExit("opening file.");    //    can't open disk file,exit
  75.     outfile.setf(ios::showpoint | ios::fixed);  //  successful, set formats 
  76.     
  77.     WriteFileHeader(cFileName, cUnionName, outfile, dHeight);
  78.     
  79.     /* caculate each vector and write to file */
  80.     for(long lCurrentStep = 0; lCurrentStep < lTotalSteps; ++lCurrentStep)
  81.     {
  82.         dAngle = dPI * 2 * ( (double)lCurrentStep / (double)lStepsPerRevolution );           
  83.         double dXpos1 = dRadius * cos(dAngle);
  84.         double dZpos1 = dRadius * sin(dAngle);                  
  85.         double dXpos2 = fabs(dRadius) * cos(dAngle);
  86.         double dZpos2 = fabs(dRadius) * sin(dAngle);              
  87.         double dYpos  = dHeight * ( (double)lCurrentStep / (double)lTotalSteps );
  88.         
  89.         WriteSphere(dXpos1, dYpos, dZpos1, dPartRadius, outfile, &lGlobalCounter);
  90.         WriteSphere(dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);         
  91.                 
  92.         if(lCurrentStep > 0) // ignore this clause the first time around
  93.         {   
  94.             WriteCone(dLastXpos1, dLastYpos, dLastZpos1, dXpos1, dYpos, dZpos1, dPartRadius, outfile, &lGlobalCounter);
  95.             WriteCone(dLastXpos2, dLastYpos, dLastZpos2, dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);                    
  96.         }                   
  97.         
  98.         lConnectorCounter++;
  99.         if(lConnectorCounter == lConnectXsteps) /* write a connector? */          
  100.         {
  101.             WriteCone(dXpos1, dYpos, dZpos1, dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);
  102.             lConnectorCounter = 0;  // reset counter to calc the next connector
  103.         }            
  104.             
  105.         dLastXpos1 = dXpos1;      // now store x, y etc in Lastx, LastY etc
  106.         dLastZpos1 = dZpos1;      //  so we can use them on the next loop to
  107.         dLastXpos2 = dXpos2;      //  connect the cones and spheres together
  108.         dLastZpos2 = dZpos2;
  109.         dLastYpos  = dYpos;        
  110.     }    
  111.     
  112.     cout << lGlobalCounter << " objects written to " << cFileName << endl;       
  113.     WriteFileEnd(outfile, lGlobalCounter);
  114.     outfile.close();   // close the output file                              
  115.     
  116.     WriteSceneFile(cFileName, cUnionName, dHeight, dRadius); // now write a scene file
  117.     return(0);
  118. }    
  119.     
  120.  
  121.  
  122. /************************** FUNCTION DEFINITIONS *****************************/
  123.  
  124.  
  125. void ErrExit(char *cMessage)
  126. {   
  127.     cerr << "\a\n\nERROR" << cMessage << "- Exiting \n";
  128.     exit(1);
  129. }    
  130.  
  131. void GetAndValidateUserInput(char *cFileName, char *cUnionName, double *dHeight, 
  132.                              double *dRadius, double *dPartRadius, 
  133.                              long *lStepsPerRevolution, long *lTotalSteps,
  134.                              long *lConnectXsteps)
  135. {       
  136.     char cBuffer[256];         // general use (user input) buffer  
  137.     const int iBUFFSIZECHAR = 80;// constant size for cin.getline() for character op's
  138.     const int iBUFFSIZENUMB = 80;// constant size for cin.getline() for numeric op's
  139.     
  140.     cout << "\nOutput file name [DNA.INC]:";
  141.     cin.getline(cBuffer,iBUFFSIZECHAR);
  142.     if(cBuffer[0] == NULL) strcpy(cBuffer, "DNA.INC");
  143.     cFileName = _strupr(cBuffer); // place capitalized contents of buffer in cFileName
  144.     
  145.     /*************** VERIFY FILENAME *****************/
  146.     for(int i = 0; i < (int)strlen(cFileName); i++)
  147.         if (cFileName[i] == '.') break;     
  148.     cFileName[i] = '.';                     
  149.     strcpy (&cFileName[i+1], "INC");
  150.     /*************************************************/
  151.     
  152.     cout << "Union name [DNA]:";
  153.     cin.getline(cBuffer,iBUFFSIZECHAR);
  154.     if(cBuffer[0] == NULL) strcpy(cBuffer, "DNA");
  155.     strcpy(cUnionName, cBuffer);
  156.         
  157.     cout << "Height (Y units) of object [50.0]:";
  158.     cin.getline(cBuffer,iBUFFSIZENUMB);    
  159.     *dHeight = atof(cBuffer); 
  160.     if( *dHeight <= 0.0 ) *dHeight = 50.0;
  161.     
  162.     cout << "Radius (X-Z) of object [10.0]:";
  163.     cin.getline(cBuffer,iBUFFSIZENUMB);    
  164.     *dRadius = atof(cBuffer);
  165.     if( *dRadius <= 0.0 ) *dRadius = 10.0;
  166.     *dRadius -= (*dRadius * 2);   // to make the result a negative
  167.         
  168.     cout << "Radius of individual objects [0.5]:";
  169.     cin.getline(cBuffer,iBUFFSIZENUMB);    
  170.     *dPartRadius = atof(cBuffer);
  171.     if(*dPartRadius <= 0.0 ) *dPartRadius = 0.5;
  172.     
  173.     cout << "Steps per revolution [30]:";
  174.     cin.getline(cBuffer,iBUFFSIZENUMB);    
  175.     *lStepsPerRevolution = atoi(cBuffer);
  176.     if(*lStepsPerRevolution <= 0 ) *lStepsPerRevolution = 30;
  177.     
  178.     cout << "Connect strands every X steps [3]:";
  179.     cin.getline(cBuffer,iBUFFSIZENUMB);    
  180.     *lConnectXsteps = atoi(cBuffer);
  181.     if(*lConnectXsteps <= 0 ) *lConnectXsteps = 3;
  182.                                          
  183.     cout << "Number of revolutions [1]:";
  184.     cin.getline(cBuffer,iBUFFSIZENUMB);    
  185.     *lTotalSteps = atoi(cBuffer);
  186.     if(*lTotalSteps <=0) *lTotalSteps = 1;
  187.     *lTotalSteps = (*lTotalSteps * *lStepsPerRevolution);  
  188.     // That * operator sure gets around!
  189. }
  190.  
  191. void ShowTitle()
  192. {
  193.     cout << "\nDNA "<< cVERSION << ", Copyright (c) 1993 Rob Bryerton\n"    
  194.          << "Creates a data file of a twisted ladder-shaped object\n"
  195.          << "(like a DNA strand) for the POV-Ray v2.x raytracer.\n";
  196. }         
  197.  
  198. inline void WriteCone(double dLastX, double dLastY,     double dLastZ, 
  199.                       double dX,     double dY,         double dZ,    
  200.                       double dRad,   ofstream& outfile, long *lGlobalCounter)
  201. {
  202.     outfile << "\n  cone{ < " <<dLastX<< ", " << dLastY << ", " <<dLastZ<< " >, " << dRad << ", < " <<dX<< ", " << dY << ", " <<dZ<< " >, " << dRad << " }";
  203.     ++*lGlobalCounter; //increment counter; note that postfix notation will not work
  204. }    
  205.  
  206. void WriteFileEnd(ofstream& outfile, long lGlobalCounter)
  207. {
  208.     outfile << "\n}\n"
  209.             << "\n// " << lGlobalCounter << " objects written to this file.\n"; 
  210. }
  211.  
  212. void WriteFileHeader(char *cFileName, char *cUnionName, ofstream& outfile, double dHeight)
  213. {
  214.     outfile << "//  This data file created by DNA.EXE " << cVERSION << " for the POV-Ray v2.x raytracer.\n"
  215.             << "//              File Name: " << cFileName << "   Union Name: " << cUnionName << endl            
  216.             
  217.             << "\n#declare " << cUnionName << " =\n"
  218.             << "union {";         
  219. }
  220.  
  221. void WriteSceneFile(char *cFileName, char *cUnionName,
  222.                      double dHeight, double dRadius)
  223. {
  224.     struct Vector{ double x,y,z;};
  225.     char cSceneFileName[80];      
  226.     ofstream sceneOutFile;        
  227.     Vector CamLocation, CamLookAt, LightLocation;    
  228.     
  229.     /****************************************/
  230.     strcpy(cSceneFileName, cFileName);
  231.     for(int i = 0; i < (int)strlen(cSceneFileName); i++)
  232.         if (cSceneFileName[i] == '.') break;         // create a SCENE filename based
  233.                                                      // on the include filename
  234.     cSceneFileName[i] = '.';                         // but with the ".POV" extension
  235.     strcpy (&cSceneFileName[i+1], "POV");
  236.     /****************************************/
  237.         
  238.     cout<< "Creating scene file " << cSceneFileName << endl;
  239.     
  240.     //  calculate camera and light vectors based on object size
  241.     
  242.     CamLocation.x = 0;
  243.     CamLocation.y = dHeight * 0.5;
  244.     CamLocation.z = dHeight - (dHeight * 2.2);
  245.     
  246.     CamLookAt.x = 0;
  247.     CamLookAt.y = dHeight * 0.5;
  248.     CamLookAt.z = 0;
  249.     
  250.     LightLocation.x = fabs(dRadius);
  251.     LightLocation.y = dHeight * 0.75;
  252.     LightLocation.z = dHeight - (dHeight * 2.0);     
  253.     
  254.     // open a disk file and write the scene file
  255.     sceneOutFile.open(cSceneFileName,ios::out);        //    try to open a disk file
  256.     if(! sceneOutFile)     ErrExit("opening file.");    //    can't open disk file,exit
  257.     sceneOutFile.setf(ios::showpoint | ios::fixed);  
  258.     
  259.     sceneOutFile << "//  This data file created by DNA.EXE " << cVERSION << " for the POV-Ray v2.x raytracer.\n"
  260.                  << "//  Scene File: " << cSceneFileName << "   Include File: " << cFileName << "   Union Name: " << cUnionName << endl
  261.                  << "#include \"colors.inc\"\n"
  262.                  << "#include \"textures.inc\"\n\n";
  263.                  
  264.     sceneOutFile << "camera {\n"
  265.                  << "    location < " << CamLocation.x << ", " << CamLocation.y << ", " << CamLocation.z << " >\n"
  266.                  << "    look_at  < " << CamLookAt.x   << ", " << CamLookAt.y   << ", " << CamLookAt.z   << " >\n"
  267.                  << "}\n\n";
  268.                  
  269.     sceneOutFile << "light_source { < " << LightLocation.x << ", " << LightLocation.y << ", " << LightLocation.z << " > color White }\n"
  270.                  
  271.                  << "\n#declare " << cUnionName << "_Texture ="
  272.                  << "\ntexture { Y_Gradient finish { ambient 0.2 } scale<1," << dHeight << ",1> }\n\n";
  273.                
  274.     sceneOutFile << "#include \"" << cFileName << "\"\n\n"
  275.                  << "object{" 
  276.                  << "\n  " << cUnionName 
  277.                  << "\n  texture{ " << cUnionName << "_Texture rotate < 0,0,25 > }"
  278.                  << "\n}\n";
  279.                                   
  280.     sceneOutFile.close();                 
  281.                  
  282. }                     
  283.  
  284. inline void WriteSphere(double dX, double dY, double dZ, double dRad, 
  285.                         ofstream& outfile, long *lGlobalCounter)
  286. {
  287.     outfile << "\n  sphere{ < " << dX << ", " << dY << ", " << dZ << " > " << dRad << " }";
  288.     ++*lGlobalCounter;//increment counter; note that postfix notation will not work
  289. }